package com.java.comprehensive.springboot_es.test;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.java.comprehensive.springboot_es.entity.User;
import org.apache.http.HttpHost;
import org.apache.lucene.util.QueryBuilder;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.IndicesClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.MaxAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;

import javax.naming.directory.SearchResult;
import java.io.IOException;
import java.util.Arrays;

/**
 * @Author: Dgg
 * @Date: 2022/2/20 22:30
 */
public class ESTestClinet {
	private static final RestHighLevelClient restHighLevelClient;
	private static final IndicesClient indices;


	static {
		//创建es 客户端
		restHighLevelClient = new RestHighLevelClient(
				RestClient.builder(new HttpHost("127.0.0.1", 9200))
		);
		indices = restHighLevelClient.indices();
	}

	public static void main(String[] args) {
		try {
//			addIndex();
//			selectIndex();
//			deleteIndex();
//			docInsert();
//			docUpdate();
//			docDelete();
//			docGet();
//			docInsertBatch();
//			docDeleteBatch();
//			docQuery();
//			docQueryBy();
//			docQueryByLimit();
//			docCombinatorialQuery();
//			docLikeQuery();
			docFunctionQuery();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	//增加索引
	private static void addIndex() throws IOException {
		//创建索引

		CreateIndexRequest createIndexRequest = new org.elasticsearch.client.indices.CreateIndexRequest("user2");
		CreateIndexResponse createIndexResponse = indices.create(createIndexRequest, RequestOptions.DEFAULT);
		boolean acknowledged = createIndexResponse.isAcknowledged();
		System.out.println("增加索引状态" + acknowledged);
		//关闭es 客户端连接
		restHighLevelClient.close();
	}

	//查询索引
	private static void selectIndex() throws IOException {
		GetIndexRequest getIndexRequest = new GetIndexRequest("user");
		GetIndexResponse getIndexResponse = indices.get(getIndexRequest, RequestOptions.DEFAULT);
		//响应
		System.out.println(getIndexResponse.getAliases());
		System.out.println(JSONUtil.parse(getIndexResponse.getMappings()));
		System.out.println(getIndexResponse.getSettings());
		restHighLevelClient.close();
	}

	//删除索引
	private static void deleteIndex() throws IOException {
		DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("user");
		AcknowledgedResponse delete = indices.delete(deleteIndexRequest, RequestOptions.DEFAULT);
		//响应
		System.out.println("删除响应：" + delete.isAcknowledged());
		restHighLevelClient.close();
	}

	//向索引插入数据
	private static void docInsert() throws IOException {
		//创建索引
		IndexRequest indexRequest = new IndexRequest();
		User user = new User();
		user.setName("zhangsan1");
		user.setSex(1);
		user.setAge(30);
		JSON parse = JSONUtil.parse(user);
		indexRequest.index("user2")
				.id("1001")
				.source(parse.toJSONString(0), XContentType.JSON);


		IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
		DocWriteResponse.Result result = response.getResult();
		System.out.println("result:" + result);
		//关闭es 客户端连接
		restHighLevelClient.close();
	}

	//局部修改数据
	private static void docUpdate() throws IOException {
		//创建索引
		UpdateRequest updateRequest = new UpdateRequest();
		User user = new User();
		user.setName("张三");
		user.setSex(1);
		user.setAge(25);
		JSON parse = JSONUtil.parse(user);
		System.out.println("json:" + parse.toJSONString(0));
		updateRequest.index("user")
				.id("1001")
				.doc(parse.toJSONString(0), XContentType.JSON);


		UpdateResponse response = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
		DocWriteResponse.Result result = response.getResult();
		System.out.println("result:" + result);
		//关闭es 客户端连接
		restHighLevelClient.close();
	}

	//查询文档数据
	private static void docGet() throws IOException {

		GetRequest getRequest = new GetRequest();
		getRequest.index("user").id("1001");
		GetResponse response = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);


		String result = response.getSourceAsString();
		System.out.println("result:" + result);
		//关闭es 客户端连接
		restHighLevelClient.close();
	}

	//删除文档数据
	private static void docDelete() throws IOException {
		//创建索引
		DeleteRequest deleteRequest = new DeleteRequest();
		deleteRequest.index("user").id("1001");
		DeleteResponse response = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);


		System.out.println("result:" + response.toString());
		//关闭es 客户端连接
		restHighLevelClient.close();
	}

	//批量增加
	private static void docInsertBatch() throws IOException {
		BulkRequest bulkRequest = new BulkRequest();
		IndexRequest indexRequest = new IndexRequest().index("user").id("1001").source(XContentType.JSON, "name", "张三", "age", 30);
		IndexRequest indexRequest2 = new IndexRequest().index("user").id("1002").source(XContentType.JSON, "name", "李四", "age", 31);
		IndexRequest indexRequest3 = new IndexRequest().index("user").id("1003").source(XContentType.JSON, "name", "王五", "age", 32);
		IndexRequest indexRequest4 = new IndexRequest().index("user").id("1004").source(XContentType.JSON, "name", "田七", "age", 20);
		IndexRequest indexRequest5 = new IndexRequest().index("user").id("1005").source(XContentType.JSON, "name", "曲八", "age", 33);
		IndexRequest indexRequest6 = new IndexRequest().index("user").id("1006").source(XContentType.JSON, "name", "窦九", "age", 55);
		IndexRequest indexRequest7 = new IndexRequest().index("user").id("1007").source(XContentType.JSON, "name", "钱十", "age", 37);
		IndexRequest indexRequest8 = new IndexRequest().index("user").id("1008").source(XContentType.JSON, "name", "邓十一", "age", 90);
		IndexRequest indexRequest9 = new IndexRequest().index("user").id("1009").source(XContentType.JSON, "name", "间十二", "age", 12);
		IndexRequest indexRequest10 = new IndexRequest().index("user").id("1010").source(XContentType.JSON, "name", "云十三", "age", 21);
		IndexRequest indexRequest11 = new IndexRequest().index("user").id("1011").source(XContentType.JSON, "name", "坑十四", "age", 19);
		bulkRequest.add(Arrays.asList(indexRequest, indexRequest2, indexRequest3, indexRequest4, indexRequest5, indexRequest6, indexRequest7, indexRequest8, indexRequest9, indexRequest10, indexRequest11));
		BulkResponse response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);

		System.out.println(response.getTook());
		BulkItemResponse[] items = response.getItems();
		for (int i = items.length - 1; i >= 0; i--) {
			System.out.println("item" + JSONUtil.parse(items[i]));
		}
	}

	//批量删除
	private static void docDeleteBatch() throws IOException {

		//创建索引
		DeleteRequest deleteRequest2 = new DeleteRequest();
		deleteRequest2.index("user").id("1002");
		DeleteRequest deleteRequest = new DeleteRequest();
		deleteRequest.index("user").id("1001");
//		DeleteResponse response = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
		BulkRequest bulkRequest = new BulkRequest();
		bulkRequest.add(Arrays.asList(deleteRequest2, deleteRequest));
		BulkResponse response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);

		System.out.println("result:" + response.toString());
		//关闭es 客户端连接
		restHighLevelClient.close();

		System.out.println(response.getTook());
	}

	//高级查询 （全量查询）
	private static void docQuery() throws IOException {
		//查询索引中所有的数据
		SearchRequest searchRequest = new SearchRequest();
		searchRequest.indices("user");
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(QueryBuilders.matchAllQuery());
		searchRequest.source(searchSourceBuilder);
		SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
		SearchHits hits = response.getHits();
		System.out.println("hits \t" + hits.getTotalHits());
		System.out.println("took \t " + response.getTook());

		hits.forEach(hit -> System.out.println("\t" + hit.getSourceAsString()));
	}

	//高级查询 条件查询
	private static void docQueryBy() throws IOException {
		//查询索引中所有的数据
		SearchRequest searchRequest = new SearchRequest();
		searchRequest.indices("user");
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(QueryBuilders.termQuery("age", "30"));
		setBuilder(searchRequest, searchSourceBuilder);
	}

	//高级查询 分页查询 排序 过滤字段
	private static void docQueryByLimit() throws IOException {
		//查询索引中所有的数据
		SearchRequest searchRequest = new SearchRequest();
		searchRequest.indices("user");
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(QueryBuilders.matchAllQuery());
		//排序
		searchSourceBuilder.sort("age", SortOrder.DESC);
		searchSourceBuilder.from(0);
		searchSourceBuilder.size(5);
		//排除什么
		String[] excluds = {"name"};
		//只显示什么
		String[] includs = {};
		searchSourceBuilder.fetchSource(includs, excluds);
		setBuilder(searchRequest, searchSourceBuilder);
	}

	//组合查询,范围查询
	private static void docCombinatorialQuery() throws IOException {
		//查询索引中所有的数据
		SearchRequest searchRequest = new SearchRequest();
		searchRequest.indices("user");

		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//		boolQueryBuilder.must(QueryBuilders.matchQuery("age", "30"));
//		boolQueryBuilder.must(QueryBuilders.boolQuery().mustNot(QueryBuilders.matchQuery("age", "30")));
//		boolQueryBuilder.must(QueryBuilders.matchQuery("name", "张三"));
//		boolQueryBuilder.should(QueryBuilders.matchQuery("age", "30"));
//		boolQueryBuilder.should(QueryBuilders.matchQuery("age", "31"));


		RangeQueryBuilder age = QueryBuilders.rangeQuery("age");
		age.gte(30);
		age.lte(40);
		searchSourceBuilder.query(age);

		setBuilder(searchRequest, searchSourceBuilder);
	}

	//模糊查询 高亮查询
	private static void docLikeQuery() throws IOException {
		//查询索引中所有的数据
		SearchRequest searchRequest = new SearchRequest();
		searchRequest.indices("user2");

		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		//模糊查询
//		FuzzyQueryBuilder fuzziness = QueryBuilders.fuzzyQuery("name", "zhang").fuzziness(Fuzziness.AUTO);
		//高亮查询
		TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "zhangsan1");
		HighlightBuilder highlightBuilder = new HighlightBuilder();
		highlightBuilder.preTags("<font color='red'>");
		highlightBuilder.postTags("</font>");
		highlightBuilder.field("name");
		searchSourceBuilder.highlighter(highlightBuilder);
		searchSourceBuilder.query(termQueryBuilder);

		setBuilder(searchRequest, searchSourceBuilder);
	}

	//聚合查询
	private static void docFunctionQuery() throws IOException {
		//查询索引中所有的数据
		SearchRequest searchRequest = new SearchRequest();
		searchRequest.indices("user");

		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		//年龄最大值
//		MaxAggregationBuilder aggregationBuilders = AggregationBuilders.max("maxAge").field("age");
//		searchSourceBuilder.aggregation(aggregationBuilders);
		AggregationBuilder field = AggregationBuilders.terms("ageGroup").field("age");
		searchSourceBuilder.aggregation(field);

		setBuilder(searchRequest, searchSourceBuilder);
	}

	private static void setBuilder(SearchRequest searchRequest, SearchSourceBuilder searchSourceBuilder) throws IOException {
		try {
			searchRequest.source(searchSourceBuilder);

			SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
			SearchHits hits = response.getHits();
			System.out.println(response);
			System.out.println("hits \t" + hits.getTotalHits());
			System.out.println("took \t " + response.getTook());

//			hits.forEach(hit -> System.out.println(hit.getSourceAsString()));
			for (SearchHit hit : hits) {
				System.out.println(hit.getSourceAsString());
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			restHighLevelClient.close();
		}


	}
}
